# -*- coding: utf-8 -*-

"""加载 wxWidgets GUI图形 Module"""
import wx
from astropy.io.fits.convenience import append
from _operator import index
"""加载serial串口 Module"""
import serial
import serial.tools.list_ports
"""加载 queue队列 Module"""
import queue
"""加载 Threading Module"""
import threading
"""加载 time 时间 Module"""
import time
import copy
 
Pos_StaticTextPort_x = 15
Pos_StaticTextPort_y = 30
Pos_StaticTextBaudRate_x = 15
Pos_StaticTextBaudRate_y = 60
Pos_StaticTextDataPos_x = 15
Pos_StaticTextDataPos_y = 90 
Pos_StaticTextCheckBit_x = 15
Pos_StaticTextCheckBit_y = 120 
Pos_StaticTextFlowCtrl_x = 15
Pos_StaticTextFlowCtrl_y = 150 
Pos_StaticTextStpbit_x = 15
Pos_StaticTextStpbit_y = 180

Pos_ComboBoxPort_x = 70
Pos_ComboBoxPort_y  = 27.5
Pos_ComboBoxBaudRate_x = 70
Pos_ComboBoxBaudRate_y= (27.5+30)
Pos_ComboBoxDataPos_x = 70
Pos_ComboBoxDataPos_y = (27.5+30*2)
Pos_ComboBoxCheckBit_x = 70
Pos_ComboBoxCheckBit_y = (27.5+30*3)
Pos_ComboBoxFlowCtrl_x = 70
Pos_ComboBoxFlowCtrl_y = (27.5+30*4)
Pos_ComboBoxStpBit_x = 70
Pos_ComboBoxStpBit_y = (27.5+30*5)

#plistport = ["2","4"]

#ComboBoxPortLLL = wx.ComboBox()

global_port_plist = []
############################################################################
#                               基础知识                                                                #
############################################################################
"""类：用来描述具有相同的属性和方法的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例"""


class BTBoxWindow(wx.Frame):
    """__init__:一个特殊的方法（构造方法）：构造函数，在生成对象时调用,用于值的初始化，,无返回参数"""
    def __init__(self,parent,title):
        """parent"""
        wx.Frame.__init__(self,parent,title= title ,size=(800,500))
        #self.contrl = wx.TextCtrl(self,style=wx.TE_MULTILINE)
        
        """创建嵌套版：Area0"""
        self.area0 = wx.Panel(self,size=(200,220),pos=(10,10))   
        """创建嵌套版: Area1"""
        #self.area1 = wx.Panel(self,size=(300,300),pos=(220,10))
        #self.area1 = wx.Panel(self,pos=(300,20))
        """"""
        #语法：wx.TextCtrl(parent, id,value='',pos=wx.DefaultPostion,size=wx.DefaultSize,style=0,validator=wx.DefaultValidator,name=wx.TextCtrlNameStr)           
        self.BTBoxText = wx.TextCtrl(self.area0,size=(550,300),pos=(220,10),style=wx.TE_MULTILINE|wx.TE_READONLY)
        
        #wx.TextCtrl  
        #grid = wx.GridBagSizer(hgap=20, vgap=20)    # 行和列的间距是5像素
        """创建菜单栏"""
        self.CreateStatusBar()
                
        """创建边框标签组"""
        #BTBoxSerialCfgList =["端口","波特率","数据位","校验位","停止位","硬件流控制"]
        #语法：Wx.RadioBox(parent, id, label, pos, size, choices[], initialdimensions, style)
        #http://xoomer.virgilio.it/infinity77/wxPython/Widgets/wx.RadioBox.html
        #self.BTCfgBox = wx.RadioBox(self,id=wx.ID_ANY,label="IPT智能跳绳串口配置", pos=(20,10), size =(50,200),choices=BTBoxSerialCfgList, majorDimension=1,style=wx.RA_SPECIFY_COLS)# style=wx.RA_SPECIFY_COLS)
        self.BTCfgBox = wx.RadioBox(self.area0 ,id=wx.ID_ANY,label=u"IPT智能跳绳串口配置", pos=(10,10), size =(200,220),majorDimension=1,style=wx.RA_SPECIFY_COLS)# style=wx.RA_SPECIFY_COLS)   
        #语法：wx.StaticText(parent, id, label, position, size, style)
        """创建静态文本：端口"""
        self.StaticTextPort = wx.StaticText(self.BTCfgBox,id=wx.ID_ANY,label=u"端口", pos=(Pos_StaticTextPort_x, Pos_StaticTextPort_y),size=(-1,-1),style=wx.FONTSTYLE_SLANT|wx.FONTWEIGHT_LIGHT)      
        #grid.Add(self.StaticTextPort, pos=(1,0))
        """创建静态文本：波特率"""
        self.StaticTextBaudRate = wx.StaticText(self.BTCfgBox,id=wx.ID_ANY,label=u"波特率",pos=(Pos_StaticTextBaudRate_x,Pos_StaticTextBaudRate_y),size=(-1,-1),style=wx.ST_ELLIPSIZE_MIDDLE)   
        """创建静态文本：数据位"""
        self.StaticTextDataPos = wx.StaticText(self.BTCfgBox,id=wx.ID_ANY,label=u"数据位",pos=(Pos_StaticTextDataPos_x,Pos_StaticTextDataPos_y),size=(-1,-1),style=wx.ST_ELLIPSIZE_MIDDLE)
        """创建静态文本：校验位"""
        self.StaticTextCheckBit = wx.StaticText(self.BTCfgBox,id=wx.ID_ANY,label=u"校验位",pos=(Pos_StaticTextCheckBit_x,Pos_StaticTextCheckBit_y),size=(-1,-1),style=wx.ST_ELLIPSIZE_MIDDLE)
        """创建静态文本：硬件流控制""" 
        self.StaticTextFlowCtrl = wx.StaticText(self.BTCfgBox,id=wx.ID_ANY,label=u"硬件流控",pos=(Pos_StaticTextFlowCtrl_x,Pos_StaticTextFlowCtrl_y),size=(-1,-1),style=wx.ST_ELLIPSIZE_MIDDLE)
        """穿件静态文本：停止位"""    
        self.StaticStopBitCtrl = wx.StaticText(self.BTCfgBox,id=wx.ID_ANY,label=u"停止位",pos=(Pos_StaticTextStpbit_x,Pos_ComboBoxStpBit_y),size=(-1,-1),style=wx.ST_ELLIPSIZE_MIDDLE)
        
        """创建列表"""
        #语法：wx.ComboBox(parent, id, value, pos, size, choices[], style)
        #http://www.cnblogs.com/ankier/archive/2012/10/10/2719003.html
        ComboBoxBaudRateList = ["9600","19200","38400","57600","115200"]
        ComboBoxDataPosList = ["5","6","7","8"]
        #ComboBoxCheckBitList = ["None","Even","Odd","Mark","Space"]
        ComboBoxCheckBitList = ["PARITY_NONE","PARITY_ODD","PARITY_EVEN"]
        #ComboBoxFlowCtrlList = ["None","RTS/CTS","XON/XOFF"]
        ComboBoxFlowCtrlList = ["False","True"]
        ComboxStpBitList = ["1","1.5","2"]
        
        #plistport.append(serialName)
        #plistport.append(serialName1)
        
        #self.ComboBoxPort = wx.ComboBox(parent=self.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxPort_x,Pos_ComboBoxPort_y),size=(100,25),choices=plistport,style=wx.TE_PROCESS_ENTER)
        #self.ComboBoxPort.Destroy()
        self.ComboBoxPort = wx.ComboBox(parent=self.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxPort_x,Pos_ComboBoxPort_y),size=(100,25),choices=self.Port_List(),style=wx.TE_PROCESS_ENTER)           

        self.ComboBoxBaudRate = wx.ComboBox(parent=self.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxBaudRate_x,Pos_ComboBoxBaudRate_y),size=(100,25),choices=ComboBoxBaudRateList,style=wx.CB_READONLY)
        self.ComboBoxDataPos = wx.ComboBox(parent=self.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxDataPos_x,Pos_ComboBoxDataPos_y),size=(100,25),choices=ComboBoxDataPosList,style=wx.CB_READONLY)
        self.ComboBoxCheckBit = wx.ComboBox(parent=self.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxCheckBit_x,Pos_ComboBoxCheckBit_y),size=(100,25),choices=ComboBoxCheckBitList,style=wx.CB_READONLY)
        self.ComboBoxFlowCtrl = wx.ComboBox(parent=self.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxFlowCtrl_x,Pos_ComboBoxFlowCtrl_y),size=(100,25),choices=ComboBoxFlowCtrlList,style=wx.CB_READONLY)
        self.ComboBoxStpBitCtrl = wx.ComboBox(parent=self.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxStpBit_x,Pos_ComboBoxStpBit_y),size=(100,25),choices=ComboxStpBitList,style=wx.CB_READONLY)
        #self.BTBoxComboBoxPortTimerself =   threading.Timer(1.0, self.BTBoxComboBoxPortTimerCallBackPravite, ["Hawk"])   
        #self.BTBoxComboBoxPortTimerself.start()
        
        #############################
        """设置菜单:文件菜单"""
        filemenu = wx.Menu()
        #语法 ：Append(id):filemenu.Append(id, item=EmptyString, helpString=EmptyString, kind=ITEM_NORMAL) 
        """"添加菜单项：关于"""
        filemenuAbout = filemenu.Append(wx.ID_ABOUT, item="关于(About)", helpString="该程序的<关于>详情", kind=wx.ITEM_NORMAL)
        """添加菜单项：关闭"""
        filemenuExit = filemenu.Append(wx.ID_EXIT, item="退出(Exit)", helpString="该程序的<退出>详情", kind=wx.ITEM_NORMAL)
        #############################
        """设置菜单：编辑菜单："""
        Editmenu = wx.Menu()
        """添加菜单项：清除"""
        EditmenuClear = Editmenu.Append(wx.ID_CLEAR,item="清除(Clear)",helpString="清除屏幕功能",kind = wx.ITEM_NORMAL)
        ##############################
        """设置菜单：视图："""
        Viewmenu = wx.Menu()
        """添加菜单项：语言"""
        VeiwmenuLanguage = Viewmenu.Append(wx.ID_ANY, item="语言(Language)", helpString="设置系统语言", kind=wx.ITEM_NORMAL)
        ##############################
        """设置菜单：工具"""
        Toolmenu = wx.Menu()
        """添加菜单项：工具箱"""
        ToolMenuToolBox = Toolmenu.Append(wx.ID_ANY,item="工具箱(ToolBox)",helpString="系统工具箱功能",kind =wx.ITEM_NORMAL)
        ##############################
        """设置菜单：运行"""
        RunMenu = wx.Menu()
        """添加菜单项：开始发送命令"""
        RunMenuStartCmd= RunMenu.Append(wx.ID_ANY, item="开始发送命令(Start Send Command)", helpString="开始发送命令",kind=wx.ITEM_NORMAL)
        """添加菜单项：清除屏幕功能"""
        RunMenuClearScreen = RunMenu.Append(wx.ID_ANY,item="清除屏幕命令(Clear Screen Command)",helpString="发送清除屏幕命令",kind=wx.ITEM_NORMAL)
        ##############################
        """设置菜单：帮助"""
        Helpmenu = wx.Menu()
        """添加菜单项：产品主页链接"""
        HelpMenuPorductHome = Helpmenu.Append(wx.ID_ANY,item="产品主页(Products Home)",helpString="关于产品主页的相关链接",kind=wx.ITEM_NORMAL)
        ##############################
        """创建菜单栏"""
        BTBoxWinMenuBar = wx.MenuBar()
        """添加菜单"""
        BTBoxWinMenuBar.Append(filemenu,u"文件(F)")
        BTBoxWinMenuBar.Append(Editmenu,u"编辑(E)")
        BTBoxWinMenuBar.Append(Viewmenu,u"视图(V)")
        BTBoxWinMenuBar.Append(Toolmenu,u"工具(T)")
        BTBoxWinMenuBar.Append(RunMenu, u"运行(R)")
        BTBoxWinMenuBar.Append(Helpmenu,u"帮助(H)")
        self.SetMenuBar(BTBoxWinMenuBar)
        ################################
        """设置events"""
        #语法：self.Bind(event, handler, source, id, id2)
        """
        http://www.cnblogs.com/ziv-chan/p/5517757.html
        """
        ################################
        self.Bind(wx.EVT_MENU, self.OnAbout, filemenuAbout, id=wx.ID_ANY, id2=wx.ID_ANY)
        self.Bind(wx.EVT_MENU, self.OnExit, filemenuExit, id=wx.ID_ANY, id2=wx.ID_ANY)
        self.Bind(wx.EVT_MENU, self.OnStartSendCmd, RunMenuStartCmd, id=wx.ID_ANY, id2=wx.ID_ANY)  
        self.Bind(wx.EVT_MENU, self.OnClearScreenFun,RunMenuClearScreen,id=wx.ID_ANY,id2=wx.ID_ANY)       
        """通过show()方法激活框架窗口。"""
        ################################
        self.Show(True)
        
    def OnClearScreenFun(self,event):
        self.BTBoxText.Clear()    
    def OnStartSendCmd(self,event):
        SendStartCmdCheckList = []
        ###调试使用
        """
        print("端口选择的索引：",self.ComboBoxPort.GetSelection())
        print("波特率选择的索引：",self.ComboBoxBaudRate.GetSelection())
        print("数据位的选择的索引：",self.ComboBoxDataPos.GetSelection())
        print("校验位的选择索引：",self.ComboBoxCheckBit.GetSelection())
        print("硬件流控制选择的索引：",self.ComboBoxFlowCtrl.GetSelection())
        """
        SendStartCmdCheckList.append(self.ComboBoxPort.GetSelection())
        SendStartCmdCheckList.append(self.ComboBoxBaudRate.GetSelection())
        SendStartCmdCheckList.append(self.ComboBoxDataPos.GetSelection())
        SendStartCmdCheckList.append(self.ComboBoxCheckBit.GetSelection())
        SendStartCmdCheckList.append(self.ComboBoxFlowCtrl.GetSelection())
        SendStartCmdCheckList.append(self.ComboBoxStpBitCtrl.GetSelection())
        ##调试使用
        #print("SendStartCmdCheckList索引列表：",SendStartCmdCheckList)
        if -1 in  SendStartCmdCheckList:
            dlg = wx.MessageDialog(self,"请选择好串口配置，再发送开始启动命令","发送启动命令提示对话框",wx.OK)
            dlg.ShowModal()#显示对话框
            dlg.Destroy()  #当结束之后关闭对话框
        else:
            #print((self.ComboBoxPort.GetItems(SendStartCmdCheckList[0]))
            
            print(self.ComboBoxPort.GetItems()[SendStartCmdCheckList[0]])
            print(self.ComboBoxBaudRate.GetItems()[SendStartCmdCheckList[1]])
            print(self.ComboBoxDataPos.GetItems()[SendStartCmdCheckList[2]])
            print(self.ComboBoxCheckBit.GetItems()[SendStartCmdCheckList[3]])
            print(self.ComboBoxFlowCtrl.GetItems()[SendStartCmdCheckList[4]])
            print(self.ComboBoxStpBitCtrl.GetItems()[SendStartCmdCheckList[5]])
            """穿件串口处理部分"""
            self.Setser = serial.Serial() 
            """
            #奇偶位
            print("serial.PARITY_NONE:",serial.PARITY_NONE)
            print("serial.PARITY_EVEN:",serial.PARITY_EVEN )
            print("serial.PARITY_ODD:",serial.PARITY_ODD)
            #停止位
            print("serial.STOPBITS_ONE",serial.STOPBITS_ONE)
            print("serial.STOPBITS_ONE_POINT_FIVE",serial.STOPBITS_ONE_POINT_FIVE)
            print("serial.STOPBITS_TWO",serial.STOPBITS_TWO)
            ###数据位
            print("serial.FIVEBITS",serial.FIVEBITS)
            print("serial.SIXBITS:",serial.SIXBITS)
            print("serial.SEVENBITS",serial.SEVENBITS)
            print("serial.EIGHTBITS",serial.EIGHTBITS)
            """
            SetBurateSetList = (9600,19200,38400,57600,115200)
            SetDataBitList = (serial.FIVEBITS,serial.SIXBITS,serial.SEVENBITS,serial.EIGHTBITS)
            SetStpBitList = (serial.STOPBITS_ONE,serial.STOPBITS_ONE_POINT_FIVE,serial.STOPBITS_TWO)
            SetCheckBitList = (serial.PARITY_NONE,serial.PARITY_EVEN,serial.PARITY_ODD)
            SetrtsctsList = (False,True)
            SetdsrdtrList = (False,True)
            SetxonxoffList = (False,True)
            """port端口确定"""
            self.Setser.port = self.ComboBoxPort.GetItems()[SendStartCmdCheckList[0]]
            """波特率设置"""
            self.Setser.baudrate = SetBurateSetList[SendStartCmdCheckList[1]]
            """数据位设置"""
            self.Setser.bytesize = SetDataBitList[SendStartCmdCheckList[2]]
            """校验位设置"""
            self.Setser.parity = SetCheckBitList[SendStartCmdCheckList[3]]
            """硬件流控制"""
            self.Setser.dsrdtr  = SetdsrdtrList[SendStartCmdCheckList[4]]
            self.Setser.rtscts = False
            self.Setser.xonxoff = False
            """停止位设置"""
            self.Setser.stopbits = SetStpBitList[SendStartCmdCheckList[5]]
            #self.Setser.in_waiting
            try:
                BTBoxComboBoxPortTimer.cancel()
                self.Setser.open()
                
                print("successful open serial port")
                """
                while 1:
                    print(self.Setser.read(12))
                """
                #self.Setser.close()
                global BTBoxSerialPortTestCallBackTimer
                BTBoxSerialPortTestCallBackTimer = threading.Timer(0.5, BTBoxSerialPortTestCallBack)
                BTBoxSerialPortTestCallBackTimer.start()
            except Exception as e:
                print("error open serial port")
                #exit()
                  
    def OnAbout(self,event):
        dlg = wx.MessageDialog(self,"IPT智能控制系统","关于对话框",wx.OK)
        dlg.ShowModal()#显示对话框
        dlg.Destroy()  #当结束之后关闭对话框
        
    def OnExit(self,event):
        self.Close(True)
  
    def Port_List(self):
        self.Com_List = [] 
        """创建列表:端口"""
        port_plist = list(serial.tools.list_ports.comports())
        """
        plist_0 = list(plist[0])
        plist_1 = list(plist[1])
        serialName = plist_0[0]
        serialName1 = plist_1[0]
        """
        for port in port_plist:
            self.Com_List.append(port[0])
        return self.Com_List
    
    def BTBoxComboBoxPortTimerCallBackPravite(self):
        print("22222Tony")
        self.BTBoxComboBoxPortTimerself.start()

"""获取串口列表"""
def GetSerialList():
    Com_List = []
    port_plist = list(serial.tools.list_ports.comports()) 
    for port in port_plist:
        Com_List.append(port[0])
    """返回Com List"""
    return Com_List   


def BTBoxSerialPortTestCallBack(): 
    #global BTBoxSerialPortTestCallBackTimer
    #self.Setser.in_waiting
    #BTBoxFrame
    datalen = BTBoxFrame.Setser.inWaiting()
    if (datalen > 0):
        #TempBuffer = []
        TempBuffer = BTBoxFrame.Setser.read(datalen)
        BTBoxFrame.BTBoxText.WriteText(TempBuffer)
    #print("My name is Tony Zhou!!!:",datalen)
    #print('get data from serial port:', TempBuffer)
    #print(TempBuffer)
    
    BTBoxSerialPortTestCallBackTimer = threading.Timer(0.5, BTBoxSerialPortTestCallBack)
    BTBoxSerialPortTestCallBackTimer.start()


def BTBoxComboBoxPortTimerCallBack(name):
    #print(BTBoxFrame.ComboBoxPort.GetValue())
    global BTBoxComboBoxPortTimer  
    NowComlist =  GetSerialList()
    #print(BTBoxFrame.ComboBoxPort.GetItems())
    #旧代码：用于测试使用
    """ 
    if (NowComlist==BTBoxFrame.Com_List):
        print("Tnnnn!!!")
    else:
        BTBoxFrame.Com_List = NowComlist
        BTBoxFrame.ComboBoxPort.Clear()
        BTBoxFrame.ComboBoxPort.Append(NowComlist)
        #print(BTBoxFrame.ComboBoxPort.GetValue())
        #BTBoxFrame.ComboBoxPort = wx.ComboBox(parent=BTBoxFrame.BTCfgBox,id=wx.ID_ANY,pos=(Pos_ComboBoxPort_x,Pos_ComboBoxPort_y),size=(100,25),choices=plistport,style=wx.TE_PROCESS_ENTER)
        #BTBoxFrame = BTBoxWindow(None,u"IPT(Intelligent Personal Trainer)智能蓝牙盒子客户端")
        print("JJJJJ!!!")
    """
    #新代码：用于实际使用
    if NowComlist != BTBoxFrame.Com_List:
        #直接赋值
        #BTBoxFrame.Com_List = NowComlist
        #浅拷贝
        #BTBoxFrame.Com_List = NowComlist.copy()
        #深拷贝
        #BTBoxFrame.Com_List = copy.deepcopy(NowComlist)
        #BTBoxFrame.ComboBoxPort.Clear()
        #BTBoxFrame.ComboBoxPort.Remove("COM14")  
        BTBoxFrame.Com_List = NowComlist    
        BTBoxFrame.ComboBoxPort.Clear()                 
        BTBoxFrame.ComboBoxPort.Append(NowComlist) 
    BTBoxComboBoxPortTimer = threading.Timer(1.0, BTBoxComboBoxPortTimerCallBack, ["Hawk"])
    BTBoxComboBoxPortTimer.start()


"""定义应用程序类的一个对象"""        
BTBoxApp = wx.App(False)
"""创建一个顶层窗口的 BTBoxWindow类的对象。 给出构造标题和尺寸参数。"""
BTBoxFrame = BTBoxWindow(None,u"IPT(Intelligent Personal Trainer)智能蓝牙盒子客户端")
"""定义一个应用程序时间类的对象"""
BTBoxComboBoxPortTimer = threading.Timer(1.0, BTBoxComboBoxPortTimerCallBack, ["Hawk"])
"""启动定时器"""
BTBoxComboBoxPortTimer.start() 
"""输入应用程序对象的主事件循环。"""
BTBoxApp.MainLoop()


        